/*
 *Copyright (c) [2019-2020]  C2comm, Inc.  All rights reserved.
 *
 *This program is free software; you can redistribute it and/or
 *modify it under the terms of the GNU General Public License
 *as published by the Free Software Foundation; either version 2
 *of the License, or (at your option) any later version.
 *
 *This program is distributed in the hope that it will be useful,
 *but WITHOUT ANY WARRANTY; without even the implied warranty of
 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *GNU General Public License for more details.
 *
 *You should have received a copy of the GNU General Public License
 *along with this program; If not, see <https://www.gnu.org/licenses/>
 */

/*
 *Vendor: C2comm
 *Version: 1.0
 *Filename: SMLocalClockControl.v
 *Target Device: Altera
 *Author : sunxiaotian@c2comm.cn
*/

`timescale 1ns/1ps
module SMLocalClockControl(
    input  wire         SYS2CORE_clk,
    input  wire         SYS2CORE_rst_n,
    input  wire [76:0]  G_current_state,
    input  wire [348:0] CONF2CORE_sm_static_conf,
    output  wire [19 :0] G_local_clk,
    input wire  [19 :0] SC2LCC_clock_corr,
	output reg         LCC2LICC_plus_1
    
);
//***************************************************
//            Intermediate variable Declaration
//***************************************************
//all wire/reg/parameter variable 
//should be declare below here 

reg [19:0]  local_clock;


assign G_local_clk[19:0] = local_clock[19:0];


always @(posedge SYS2CORE_clk or negedge SYS2CORE_rst_n) begin
    if(~SYS2CORE_rst_n) begin
		LCC2LICC_plus_1 <= 1'b0;
		local_clock[19:0] <= 20'b0;
		//clock_corr[19:0] <= 20'b0;
    end
    else begin
		/**Plus_1**/
		local_clock[19:0] <= local_clock[19:0] +1'b1;
		if((local_clock[19:0]+1'b1) == (CONF2CORE_sm_static_conf[329:310])) begin
			local_clock[19:0] <= 20'b0; 
			LCC2LICC_plus_1 <= 1'b1;
		end
		else begin
			LCC2LICC_plus_1 <= 1'b0;
		end
		if(G_current_state[76:69] == 8'b0000_0001) begin 
			if(G_current_state[65] == 1'b1) begin //C0_S 
				local_clock[19:0] <= 20'b0; 
			end
			else if(G_current_state[66] == 1'b1) begin //C1_S 
				local_clock[19:0] <= 20'b0; 
			end
			else if(G_current_state[67] == 1'b1) begin //C2_S 
				local_clock[19:0] <= CONF2CORE_sm_static_conf[79:60]; 
			end
			else if(G_current_state[68] == 1'b1) begin //C3_S 
				local_clock[19:0] <= CONF2CORE_sm_static_conf[79:60]; 
			end
		end
		else if(G_current_state[76:69] == 8'b0000_0100) begin 
			if(G_current_state[50] == 1'b1) begin //C0_S 
				local_clock[19:0] <= 20'b0; 
			end
			else if(G_current_state[51] == 1'b1) begin //C1_S 
				local_clock[19:0] <= 20'b0; 
			end
			else if(G_current_state[52] == 1'b1) begin //C2_S 
				local_clock[19:0] <= 20'b0; 
			end
			else if(G_current_state[53] == 1'b1) begin //C3_S 
				local_clock[19:0] <= 20'b0; 
			end
			else if(G_current_state[54] == 1'b1) begin //C4_S 
				local_clock[19:0] <= CONF2CORE_sm_static_conf[79:60]; 
			end
			else if(G_current_state[55] == 1'b1) begin //C5_S 
				local_clock[19:0] <= CONF2CORE_sm_static_conf[79:60]; 
			end
		end
		else if(G_current_state[76:69] == 8'b0000_1000) begin 
			if(G_current_state[42] == 1'b1) begin //C0_S 
				local_clock[19:0] <= 20'b0; 
			end
			else if(G_current_state[43] == 1'b1) begin //C1_S 
				local_clock[19:0] <= 20'b0; 
			end
			else if(G_current_state[44] == 1'b1) begin //C2_S 
				local_clock[19:0] <= 20'b0; 
			end
			else if(G_current_state[45] == 1'b1) begin //C3_S 
				local_clock[19:0] <= 20'b0; 
			end
			else if(G_current_state[46] == 1'b1) begin //C4_S 
				local_clock[19:0] <= 20'b0; 
			end
		end
		else if(G_current_state[76:69] == 8'b0001_0000) begin 
			if(G_current_state[36] == 1'b1) begin //C0_S 
				local_clock[19:0] <= 20'b0; 
			end
			else if(G_current_state[37] == 1'b1) begin //C1_S 
				local_clock[19:0] <= 20'b0; 
			end
			else if(G_current_state[38] == 1'b1) begin //C2_S 
				local_clock[19:0] <= 20'b0; 
			end
		end
		else if(G_current_state[76:69] == 8'b0010_0000) begin 
			if(G_current_state[25] == 1'b1) begin //C0_S 
				local_clock[19:0] <= 20'b0; 
			end
			else if(G_current_state[27] == 1'b1) begin //C2_S 
				local_clock[19:0] <= 20'b0; 
			end
			else if(G_current_state[31] == 1'b1) begin //C6_S 
				local_clock[19:0] <= local_clock[19:0]+SC2LCC_clock_corr[19:0]+1'b1; 
			end
			else if(G_current_state[32] == 1'b1) begin //C7_S 
				local_clock[19:0] <= 20'b0; 
			end
		end
		else if(G_current_state[76:69] == 8'b0100_0000) begin 
			if(G_current_state[13] == 1'b1) begin //C0_S 
				local_clock[19:0] <= 20'b0; 
			end
			else if(G_current_state[15] == 1'b1) begin //C2_S 
				local_clock[19:0] <= 20'b0; 
			end
			else if(G_current_state[16] == 1'b1) begin //C3_S 
				local_clock[19:0] <= 20'b0; 
			end
			else if(G_current_state[20] == 1'b1) begin //C7_S 
				local_clock[19:0] <= local_clock[19:0]+SC2LCC_clock_corr[19:0]+1'b1; 
			end
			else if(G_current_state[21] == 1'b1) begin //C8_S 
				local_clock[19:0] <= 20'b0; 
			end
		end
		else if(G_current_state[76:69] == 8'b1000_0000) begin 
			if(G_current_state[3] == 1'b1) begin //C0_S 
				local_clock[19:0] <= 20'b0; 
			end
			else if(G_current_state[6] == 1'b1) begin //C3_S 
				local_clock[19:0] <= 20'b0; 
			end
			else if(G_current_state[8] == 1'b1) begin //C5_S 
				local_clock[19:0] <= local_clock[19:0]+SC2LCC_clock_corr[19:0]+1'b1; 
			end
			else if(G_current_state[9] == 1'b1) begin //C6_S 
				local_clock[19:0] <= 20'b0; 
			end
		end
	
    end
end



endmodule